<template>
  <div class="model-container">
    <div ref="rendererContainer" class="renderer-wrapper"></div>
    <div v-if="loadingProgress < 100" class="loading-overlay">
      <div class="loading-bar" :style="{ width: loadingProgress + '%' }"></div>
    </div>
  </div>
</template>

<script>
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';

// 配置常量
const CONFIG = {
  BACKGROUND_COLOR: 0xeeeeee,
  CAMERA: {
    NEAR: 0.1,               // 减小近平面距离
    FAR: 100000,
    FAR_MULTIPLIER: 100,
    FOV: 45                 // 增大视场角
  },
  CONTROLS: {
    ZOOM_SPEED: 3.5,          // 大幅提升缩放速度
    MIN_ZOOM_RATIO: 0.001,    // 允许极近距离观察
    MAX_ZOOM_RATIO: 50,
    PAN_SPEED: 1.2            // 提升平移速度
  },

  LIGHTING: {
    AMBIENT: 0xffffff,
    AMBIENT_INTENSITY: 1.2,
    DIRECTIONAL: {
      COLOR: 0xffffff,
      INTENSITY: 2.0,
      POSITION: [5, 10, 7.5]
    }
  }
};

export default {
  name: 'ModelViewer',
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      controls: null,
      mixer: null,
      loadingProgress: 0,
      frameId: null
    };
  },
  mounted() {
    this.initScene();
    this.setupEventListeners();
  },
  beforeDestroy() {
    this.cleanupResources();
  },
  methods: {
    // 初始化Three.js核心组件
    initScene() {
      this.createRenderer();
      this.createCamera();
      this.createScene();
      this.setupLighting();
      this.setupControls();
      this.loadModel();
    },

    // 创建渲染器
    createRenderer() {
      this.renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true
      });
      this.renderer.setPixelRatio(window.devicePixelRatio);
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      this.$refs.rendererContainer.appendChild(this.renderer.domElement);
    },

    // 创建相机
    createCamera() {
      this.camera = new THREE.PerspectiveCamera(
        CONFIG.CAMERA.FOV,
        window.innerWidth / window.innerHeight,
        CONFIG.CAMERA.NEAR,
        CONFIG.CAMERA.FAR_MULTIPLIER * 1
      );
    },

    // 创建场景
    createScene() {
      this.scene = new THREE.Scene();
      this.scene.background = new THREE.Color(CONFIG.BACKGROUND_COLOR);
    },

    // 灯光设置
    setupLighting() {
      const ambientLight = new THREE.AmbientLight(
        CONFIG.LIGHTING.AMBIENT,
        CONFIG.LIGHTING.AMBIENT_INTENSITY
      );

      const directionalLight = new THREE.DirectionalLight(
        CONFIG.LIGHTING.DIRECTIONAL.COLOR,
        CONFIG.LIGHTING.DIRECTIONAL.INTENSITY
      );
      directionalLight.position.set(...CONFIG.LIGHTING.DIRECTIONAL.POSITION);

      this.scene.add(ambientLight, directionalLight);
    },

    // 控制器设置
    setupControls() {
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      Object.assign(this.controls, {
        enableDamping: true,
        zoomSpeed: CONFIG.CONTROLS.ZOOM_SPEED,
        screenSpacePanning: true
      });
    },

    // 模型加载
    async loadModel() {
      try {
        const loader = this.createConfiguredLoader();
        const gltf = await loader.loadAsync(
          '/glb/nhcj.glb',
          this.onProgress
        );

        this.processLoadedModel(gltf);
        this.setupCameraPosition(gltf.scene);
        this.startAnimationLoop();
      } catch (error) {
        this.handleLoadingError(error);
      }
    },

    // 创建带配置的加载器
    createConfiguredLoader() {
      const loader = new GLTFLoader();
      const dracoLoader = new DRACOLoader();
      dracoLoader.setDecoderPath('/draco/');
      loader.setDRACOLoader(dracoLoader);
      return loader;
    },

    // 处理加载完成的模型
    processLoadedModel(gltf) {
      const model = gltf.scene;
      this.scene.add(model);

      if (gltf.animations?.length) {
        this.mixer = new THREE.AnimationMixer(model);
        gltf.animations.forEach(clip =>
          this.mixer.clipAction(clip).play()
        );
      }
    },

    // 设置相机位置
    setupCameraPosition(model) {
      const box = new THREE.Box3().setFromObject(model);
      const center = box.getCenter(new THREE.Vector3());
      // const size = box.getSize(new THREE.Vector3());

      // // 添加模型自动缩放（应对超大尺寸模型）
      // const maxDim = Math.max(size.x, size.y, size.z);
      // const scaleFactor = 1 / (maxDim || 1); // 防止除零错误
      // model.scale.setScalar(scaleFactor);     // 归一化模型尺寸
      //
      // // 重新计算尺寸
      // const scaledSize = size.multiplyScalar(scaleFactor);
      // const effectiveMaxDim = Math.max(scaledSize.x, scaledSize.y, scaledSize.z);
      //
      // // 动态计算缩放范围
      // const baseDistance = effectiveMaxDim * 2;
      // const minDistance = effectiveMaxDim * CONFIG.CONTROLS.MIN_ZOOM_RATIO;
      // const maxDistance = effectiveMaxDim * CONFIG.CONTROLS.MAX_ZOOM_RATIO;
      //
      // // 设置相机参数
      this.camera.position.set(
        center.x ,
        center.y,
        center.z
      );

      // this.camera.position.set(0, 50, 100); // 初始相机位置
      // this.camera.near = CONFIG.CAMERA.NEAR;
      // this.camera.far = CONFIG.CAMERA.FAR;
      // this.camera.updateProjectionMatrix();

      // 强制更新控制器参数
      // this.controls.minDistance = 0.0001;
      // this.controls.maxDistance = 1;
      // this.controls.update();

      // 调试输出
      // console.log('归一化后模型尺寸:', scaledSize);
      // console.log('有效缩放范围:',
      //   `最小: ${minDistance.toFixed(4)} 最大: ${maxDistance.toFixed(2)}`);
    },

    // 动画循环
    startAnimationLoop() {
      const animate = () => {
        this.frameId = requestAnimationFrame(animate);
        this.controls.update();
        if (this.mixer) this.mixer.update(0.0167);
        this.renderer.render(this.scene, this.camera);
      };
      animate();
    },

    // 事件处理
    setupEventListeners() {
      window.addEventListener('resize', this.handleResize);
    },

    handleResize() {
      this.camera.aspect = window.innerWidth / window.innerHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(window.innerWidth, window.innerHeight);
    },

    onProgress(event) {
      this.loadingProgress = (event.loaded / event.total) * 100;
    },

    handleLoadingError(error) {
      console.error('模型加载失败:', error);
      // 这里可以添加错误处理逻辑
    },

    // 资源清理
    cleanupResources() {
      cancelAnimationFrame(this.frameId);
      window.removeEventListener('resize', this.handleResize);

      if (this.controls) {
        this.controls.dispose();
      }

      if (this.renderer) {
        this.renderer.dispose();
        this.$refs.rendererContainer.removeChild(this.renderer.domElement);
      }

      this.scene.traverse(child => {
        if (child.isMesh) {
          child.geometry.dispose();
          if (Array.isArray(child.material)) {
            child.material.forEach(m => m.dispose());
          } else {
            child.material.dispose();
          }
        }
      });
    }
  }
};
</script>

<style>
.model-container {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

.renderer-wrapper {
  width: 100%;
  height: 100%;
}

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background: rgba(255, 255, 255, 0.1);
}

.loading-bar {
  height: 100%;
  background: #2196f3;
  transition: width 0.3s ease;
}
</style>